﻿/// <summary>
/// <Filename>: Motion_Excel.cs
/// Author: Jiang Xiaolong
/// Created: 2015.01.30
/// Version: 1.0
/// Company: Sunnytech
/// Function: Excel运动信息处理类
///
/// Changed By:
/// Modification Time:
/// Discription:
/// <summary>
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using Motion.MotionPlatform.Tools;

using Expression.api;
using Expression.impl;

namespace Motion.MotionPlatform
{
	//基本运动类
	public class BasicMotion : IMotion
	{
		//默认为Active
		public CurrentState State
		{
			get { return _state; }
			set { _state = value; }
		}
		private CurrentState _state = CurrentState.Active;
		//时间参数
		//正常速率时间
		public float StandardTime
		{
			get { return _standardTime; }
			set { _standardTime = value; }
		}
		private float _standardTime = 0f;
		//运动开始时间
		public float StartTime
		{
			get { return _startTime; }
			set { _startTime = value; }
		}
		private float _startTime = 0f;
		//运动结束时间
		public float EndTime
		{
			get { return _endTime; }
			set { _endTime = value; }
		}
		private float _endTime = 0f;

		//速率
		public float SpeedRate
		{
			get { return Motion_Data.SpeedRate; }
			set { Motion_Data.SpeedRate = value; }
		}
		//暂停状态
		public bool PauseControl
		{
			get { return Motion_Data.PauseControl; }
			set { Motion_Data.PauseControl = value; }
		}

		//运动类型
		public MotionType CurrentMotion = MotionType.MoveOnly;
		//本次移动的物体，用于确定模型结构
		public Transform ParentTrans = null;
		public List<Transform> ChildList = new List<Transform>();
		public List<Transform> ParentList = new List<Transform>();
		//起始信息
		public Vector3 StartPos = new Vector3(0f, 0f, 0f);
		public Vector3 StartEurler = new Vector3(0f, 0f, 0f);
		//终止信息
		public Vector3 EndPos = new Vector3(0f, 0f, 0f);
		public Vector3 EndEurler = new Vector3(0f, 0f, 0f);
		//速度参数
		public float MoveSpeed = 1.0f;
		public Vector3 SpeedVector = new Vector3(0f, 0f, 0f);
		public float RotateSpeed = 1.0f;
		public Vector3 AngleVector = new Vector3(0f, 0f, 0f);
		//旋转中心
		public Vector3 RotateCenter = new Vector3(0f, 0f, 0f);
		public Vector3 RotateAxis = new Vector3(0f, 0f, 0f);
		//移动加速度
		public Vector3 AccelerateVec = new Vector3(0f, 0f, 0f);


		public bool IsActive = false;  //组合运动时的当前激活实例

		public CRSpline crSpline = new CRSpline();  //CR样条
		private int currentIndex = 0;  //当前二分法找到的参数序号
		private float viewTimeRate = 0f;  //二分法找到的参数对应的时间
		private float currentTimeRate = 0f;  //记录当前时间进程
		public float startTimeRate = 0f;  //记录变速时的当前时间进程
		private float restTime = 0f;  //剩余时间
		private float postTime = 0f;  //已经过去的时间
		private float lastFrameTime = 0f;  //记录上一帧时间

		//修改参数
		public string returnValue = "";
		public float targetValue = 0;

		public BasicMotion()
		{
			ChildList = new List<Transform>();
			ParentList = new List<Transform>();
		}


		public void ListCopy(List<Transform> child_list, List<Transform> parent_list)
		{
			ChildList.Clear();
			ParentList.Clear();
			for (int i = 0; i < child_list.Count; i++)
			{
				ChildList.Add(child_list[i]);
			}
			for (int i = 0; i < parent_list.Count; i++)
			{
				ParentList.Add(parent_list[i]);
			}
		}

		//空物体
		public GameObject EmptyObj = null;

		public void Init()
		{
			restTime = EndTime;
			//模型结构确定
			if (CurrentMotion == MotionType.MoveRotateSingle || CurrentMotion == MotionType.MoveRotateEvery)
			{  //平移+旋转
				for (int i = 0; i < ChildList.Count; i++)
				{
					ChildList[i].parent = EmptyObj.transform;
				}
			}
			else
			{
				for (int i = 0; i < ChildList.Count; i++)
				{
					ChildList[i].parent = ParentTrans;
				}
				if (CurrentMotion == MotionType.VisualPath)
				{
					if (Motion_Data.isEditor)  //显示绿线初始化
					{
						Type _t = Motion_TypeGet.MotionTypeGet("ReflectionManager");
						if (!MotionPlatformData.st_ReflectionManager && _t != null)
						{
							MotionPlatformData.st_ReflectionManager = (MonoBehaviour)GameObject.FindObjectOfType(_t);
						}

						if (MotionPlatformData.st_ReflectionManager && _t != null)
						{
							MethodInfo methodInfo = _t.GetMethod("AddUnit");
							BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;
							object[] para = new object[] { ParentTrans, crSpline.controlPoints.ToArray() };
							methodInfo.Invoke(MotionPlatformData.st_ReflectionManager, flag, Type.DefaultBinder, para, null);
						}
					}
				}
			}
		}

		//暂停控制
		public void Pause(bool play_status)  //接口方法
		{

		}

		//速率控制
		public void ChangeRate(float current_rate, float current_time)  //接口方法
		{
			//直接设置位置不需要改变速率
			if (CurrentMotion != MotionType.SetPos && CurrentMotion != MotionType.SetLuoDingPos && CurrentMotion != MotionType.SetTool)
			{
				//如果为非激活状态
				if (State != CurrentState.Active)
				{
					StartTime = 0;
					EndTime = SpeedRate * EndTime / current_rate;
				}
				else
				{
					//激活状态
					startTimeRate = currentTimeRate;
					postTime = current_time;
					EndTime = current_time + (EndTime - current_time) * SpeedRate / current_rate;
					if (CurrentMotion == MotionType.AccelerateMove)
					{
						StartPos = ParentTrans.localPosition;
						SpeedVector = SpeedVector + AccelerateVec * (current_time - StartTime) * SpeedRate;
					}
					else if (CurrentMotion == MotionType.RandomMotion)
					{
						StartPos = ParentTrans.position;
						StartEurler = ParentTrans.eulerAngles;
					}
					restTime = (EndTime - postTime) / (1f - startTimeRate);
					StartTime = current_time;
				}
			}
		}

		//通用运动驱动函数
		public void Move(float current_time, float speed_rate, float delta_time)  //接口方法
		{
			if (TimeRate(current_time) > 1.001f || current_time > EndTime)
			{
				return;
			}
			else
			{
				lastFrameTime = current_time;
			}
			if (CurrentMotion == MotionType.MoveOnly)
			{
				//匀速直线运动
				//ParentTrans.Translate(SpeedVector * delta_time * speed_rate, Space.Self);

				ParentTrans.localPosition += SpeedVector * delta_time * speed_rate;

				//修改参数
				if (returnValue != "")
				{
					VariableManager.SetValue(returnValue, (SpeedVector * delta_time * speed_rate).magnitude + (float)VariableManager.GetValue(returnValue), true);
				}
			}
			else if (CurrentMotion == MotionType.ProgramMove)
			{
				//匀速直线运动
				ParentTrans.Translate(SpeedVector * delta_time * speed_rate, Space.Self);


			}
			else if (CurrentMotion == MotionType.WorldMove)
			{
				//在世界坐标内移动
				ParentTrans.Translate(SpeedVector * delta_time * speed_rate, Space.World);
			}
			else if (CurrentMotion == MotionType.AccelerateMove)
			{
				//匀加速直线运动 
				ParentTrans.position = StartPos + SpeedVector * (current_time - StartTime) * speed_rate +
					0.5f * AccelerateVec * ((current_time - StartTime) * speed_rate) * ((current_time - StartTime) * speed_rate);
			}
			else if (CurrentMotion == MotionType.RotateOnly)
			{
				//旋转运动
				ParentTrans.RotateAround(RotateCenter, RotateAxis, RotateSpeed * delta_time * speed_rate);

				//修改参数
				if(returnValue != ""){
					VariableManager.SetValue(returnValue, RotateSpeed * delta_time * speed_rate + (float)VariableManager.GetValue(returnValue), true);
				}
			}
			else if (CurrentMotion == MotionType.MoveRotateSingle)
			{
				//平移+旋转，围绕某一个
				if (SpeedVector != Vector3.zero)
					EmptyObj.transform.Translate(SpeedVector * delta_time * SpeedRate, Space.World);
				EmptyObj.transform.Rotate(RotateAxis * RotateSpeed * delta_time * SpeedRate, Space.Self);
			}
			else if (CurrentMotion == MotionType.MoveRotateEvery)
			{
				//平移+旋转，围绕各自
				if (SpeedVector != Vector3.zero)
					EmptyObj.transform.Translate(SpeedVector * delta_time * SpeedRate, Space.World);
				for (int i = 0; i < ChildList.Count; i++)
				{
					ChildList[i].Rotate(RotateAxis * RotateSpeed * delta_time * SpeedRate, Space.Self);
				}
			}
			else if (CurrentMotion == MotionType.RandomMotion)
			{
				//任意移动
				if (SpeedVector != Vector3.zero)
					ParentTrans.position = StartPos + SpeedVector * (current_time - StartTime) * speed_rate;
				if (AngleVector != Vector3.zero)
					ParentTrans.eulerAngles = StartEurler + AngleVector * (current_time - StartTime) * speed_rate;
			}
			else if (CurrentMotion == MotionType.VisualPath)
			{
				//可视化路径移动
				ParentTrans.position = crSpline.Interp(TimeRate(current_time));
				ParentTrans.eulerAngles = crSpline.EulerAngleLerp(TimeRate(current_time), ref currentIndex, ref viewTimeRate);
			}
		}

		//变速后的时间比率
		private float TimeRate(float current_time)
		{
			currentTimeRate = startTimeRate + (current_time - postTime) / restTime;
			return currentTimeRate;
		}

		//时间控制
		public bool TimesUp(float current_time)
		{
			if (current_time > EndTime)
			{
				//Debug.Log("Excel: " + currentTimeRate + "---" + (EndTime - lastFrameTime));
				if (EndTime - lastFrameTime > 0)  //最后没运行的时间修正
				{
					//Debug.Log("Excel: " + (EndTime - lastFrameTime));
					TimeCorrection(EndTime - lastFrameTime, SpeedRate);
				}
				return true;
			}
			else
				return false;
		}

		//后处理，主要是位置修正
		public void PostProcess()
		{
			if (CurrentMotion == MotionType.MoveOnly || CurrentMotion == MotionType.AccelerateMove
				|| CurrentMotion == MotionType.WorldMove || CurrentMotion == MotionType.ProgramMove)
			{  //直线运动
				ParentTrans.position = EndPos;

				//修改参数
				if (returnValue != "" && CurrentMotion == MotionType.MoveOnly)
				{
					VariableManager.SetValue(returnValue, targetValue, true);
				}
			}
			else if (CurrentMotion == MotionType.RotateOnly || CurrentMotion == MotionType.RandomMotion ||
			   CurrentMotion == MotionType.SetPos)
			{  //旋转运动和任意运动，还有直接设置位置
				ParentTrans.position = EndPos;
				ParentTrans.eulerAngles = EndEurler;

				//修改参数
				if (returnValue != "" && CurrentMotion == MotionType.RotateOnly)
				{
					VariableManager.SetValue(returnValue, targetValue, true);
				}
			}
			else if (CurrentMotion == MotionType.SetTool)
			{  //新加工具子物体位置和角度设置；
				//ParentTrans.position = EndPos;
				//ParentTrans.eulerAngles = EndEurler;
				MotionPlatformData.toolsManager.PositionReset(ParentTrans.name);
			}
			else if (CurrentMotion == MotionType.MoveRotateSingle)
			{
				if (SpeedVector != Vector3.zero)
					EmptyObj.transform.position = EndPos;
				EmptyObj.transform.eulerAngles = EndEurler;
			}
			else if (CurrentMotion == MotionType.MoveRotateEvery)
			{  //平移+旋转
				if (SpeedVector != Vector3.zero)
					EmptyObj.transform.position = EndPos;
			}
			else if (CurrentMotion == MotionType.VisualPath)
			{
				ParentTrans.position = crSpline.controlPoints[crSpline.controlPoints.Count - 1];
				ParentTrans.eulerAngles = crSpline.rotationList[crSpline.rotationList.Count - 1];
				if (Motion_Data.isEditor)  //消除绿线初始化
				{
					Type _t = Motion_TypeGet.MotionTypeGet("ReflectionManager");
					if (!MotionPlatformData.st_ReflectionManager && _t != null)
					{
						MotionPlatformData.st_ReflectionManager = (MonoBehaviour)GameObject.FindObjectOfType(_t);
					}

					if (MotionPlatformData.st_ReflectionManager && _t != null)
					{
						MethodInfo methodInfo = _t.GetMethod("DestroyUnit");
						BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;
						object[] para = new object[] { ParentTrans };
						methodInfo.Invoke(MotionPlatformData.st_ReflectionManager, flag, Type.DefaultBinder, para, null);
					}
				}
			}
			else if (CurrentMotion == MotionType.SetLuoDingPos)
			{
				//螺钉自动摆放
				ParentTrans.position = EndPos;
				ParentTrans.eulerAngles = EndEurler;
				for (int i = 0; i < ChildList.Count; i++)
				{
					ChildList[i].eulerAngles = ParentTrans.eulerAngles;
					ChildList[i].position = ParentTrans.position + (i + 1) * SpeedVector;
				}
			}

			DetachChildren();
			if (EmptyObj != null)
				GameObject.DestroyImmediate(EmptyObj);
		}

		//最后没运行的时间修正
		private void TimeCorrection(float delta_time, float speed_rate)
		{
			if (CurrentMotion == MotionType.MoveOnly)
			{
				//匀速直线运动
				//ParentTrans.Translate(SpeedVector * delta_time * speed_rate, Space.Self);
				ParentTrans.localPosition += SpeedVector * delta_time * speed_rate;
			}
			else if (CurrentMotion == MotionType.ProgramMove)
			{
				//匀速直线运动
				ParentTrans.Translate(SpeedVector * delta_time * speed_rate, Space.Self);
			}
			else if (CurrentMotion == MotionType.WorldMove)
			{
				//在世界坐标内移动
				ParentTrans.Translate(SpeedVector * delta_time * speed_rate, Space.World);
			}
			else if (CurrentMotion == MotionType.AccelerateMove)
			{
				//匀加速直线运动 
				ParentTrans.localPosition = StartPos + SpeedVector * (EndTime - StartTime) * speed_rate +
					0.5f * AccelerateVec * ((EndTime - StartTime) * speed_rate) * ((EndTime - StartTime) * speed_rate);
			}
			else if (CurrentMotion == MotionType.RotateOnly)
			{
				//旋转运动
				ParentTrans.RotateAround(RotateCenter, RotateAxis, RotateSpeed * delta_time * speed_rate);
			}
			else if (CurrentMotion == MotionType.MoveRotateSingle)
			{
				//平移+旋转，围绕某一个
				if (SpeedVector != Vector3.zero)
					EmptyObj.transform.Translate(SpeedVector * delta_time * SpeedRate, Space.World);
				EmptyObj.transform.Rotate(RotateAxis * RotateSpeed * delta_time * SpeedRate, Space.Self);
			}
			else if (CurrentMotion == MotionType.MoveRotateEvery)
			{
				//平移+旋转，围绕各自
				if (SpeedVector != Vector3.zero)
					EmptyObj.transform.Translate(SpeedVector * delta_time * SpeedRate, Space.World);
				for (int i = 0; i < ChildList.Count; i++)
				{
					ChildList[i].Rotate(RotateAxis * RotateSpeed * delta_time * SpeedRate, Space.Self);
				}
			}
			else if (CurrentMotion == MotionType.RandomMotion)
			{
				//任意移动
				if (SpeedVector != Vector3.zero)
					ParentTrans.position = StartPos + SpeedVector * (EndTime - StartTime) * speed_rate;
				if (AngleVector != Vector3.zero)
					ParentTrans.eulerAngles = StartEurler + AngleVector * (EndTime - StartTime) * speed_rate;
			}
			else if (CurrentMotion == MotionType.VisualPath)
			{
				//可视化路径移动
				ParentTrans.position = crSpline.Interp(TimeRate(EndTime));
				ParentTrans.eulerAngles = crSpline.EulerAngleLerp(TimeRate(EndTime), ref currentIndex, ref viewTimeRate);
			}
		}

		//解除之前建立的父子关系，恢复到初始状态
		private void DetachChildren()
		{
			for (int i = 0; i < ChildList.Count; i++)
			{
				ChildList[i].parent = ParentList[i];
			}
		}
	}


	/// <summary>
	/// Excel运动信息提取管理类，相当于工厂；
	/// </summary>
	public class Motion_ExcelInfoManager : IMotionInfoManager
	{
		/// <summary>
		/// 信息获取函数，用反射的方式创建Program相应的解析类；
		/// </summary>
		/// <param name="motion_symbol">当前运动标识符；</param>
		/// <param name="data_row">当前传入的Excel数据行；</param>
		/// <param name="row_id">当前行对应ID号；</param>
		/// <param name="group_table">当前Group数据表；</param>
		/// <param name="motion_list">简单运动类列表；</param>
		/// <param name="complex_motion_list">复合运动类列表；</param>
		/// <returns>解析是否正确；</returns>
		public bool InfoGet(string motion_symbol, int state, DataRow data_row, string row_id, DataTable group_table, IList<IMotion> motion_list, IList<IList<IMotion>> complex_motion_list)
		{
			string excelMotionID = ((string)data_row[3].ToString()).ToUpper();
			if (Motion_Data.MotionFunctionAllow(motion_symbol, excelMotionID, state))
			{
				if (Motion_Data.MotionFunctionClassDic[motion_symbol].ContainsKey(excelMotionID))
				{
					Type _t = Motion_TypeGet.MotionTypeGet("Motion.MotionPlatform." + Motion_Data.MotionFunctionClassDic[motion_symbol][excelMotionID]);
					//实例化相应的解析类
					IMotionFunctionInfo infoInstance = (IMotionFunctionInfo)Activator.CreateInstance(_t);

					////将Excel中参数转换成参数表里面的数据
					//Motion_Compute.ExcelDataAnalysis(ref data_row);
					return infoInstance.InfoGet(data_row, row_id, group_table, motion_list, complex_motion_list);
				}
				else
				{
					Debug.LogError("Excel运动标志符：" + excelMotionID + "，不含有该运动标志符对应的解析类，请询问相关程序猿！");
					return false;
				}
			}
			else
			{
				return true;
			}
		}
	}



	/// <summary>
	/// 简单平移；
	/// </summary>
	public class Motion_Excel_SimpleMove : IMotionFunctionInfo
	{

		public bool InfoGet(DataRow data_row, string row_id, DataTable group_table, IList<IMotion> motion_list, IList<IList<IMotion>> complex_motion_list)
		{
			BasicMotion _simpleMotion = new BasicMotion();


			bool isRight = true;
			//运动类型
			if (data_row[4].ToString() == "")
			{  //匀速直线
				_simpleMotion.CurrentMotion = MotionType.MoveOnly;
			}
			else
			{  //匀加速直线运动
				_simpleMotion.CurrentMotion = MotionType.AccelerateMove;
			}
			//Group Column
			int groupColumn = Motion_Compute.IntConversion(data_row[2].ToString(), ref isRight) + 1;
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group填写错误！");
				}
				return false;
			}
			if (groupColumn >= group_table.Columns.Count || groupColumn <= 0)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group组号超出范围");
				}
				return false;
			}
			//运动物体信息
			string objName = "";
			objName = (string)group_table.Rows[0][groupColumn].ToString();
			try
			{
				_simpleMotion.ParentTrans = GameObject.Find(objName).transform;
			}
			catch
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，简单平移Group第一个物体填写错误，" + objName + "该物体在场景中不存在！");
				}
				return false;
			}
			for (int i = 1; i < group_table.Rows.Count; i++)
			{
				objName = (string)group_table.Rows[i][groupColumn].ToString();
				if (objName == "")
					break;
				Transform tempTrans = null;
				try
				{
					tempTrans = GameObject.Find(objName).transform;
				}
				catch
				{
					isRight = false;
					Debug.LogError(objName + "，该物体在场景中不存在！");
					continue;
				}
				_simpleMotion.ChildList.Add(tempTrans);
				_simpleMotion.ParentList.Add(tempTrans.parent);
			}
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，Group号对应的Group表填写有错误！");
				}
				return false;
			}
			//起始信息记录
			_simpleMotion.StartPos = _simpleMotion.ParentTrans.position;
			_simpleMotion.StartEurler = _simpleMotion.ParentTrans.eulerAngles;
			//运动向量提取
			string tmpVec = data_row[6].ToString();
			//修改参数
			if (tmpVec.Contains("$") && tmpVec[0] != '$')
			{
				string[] tmpRotateDegrees = tmpVec.Split('$');
				tmpVec = tmpRotateDegrees[0];

				//TODO_ERROR:变量检查
				if (ExpressionManager.IsCreatedVariable(tmpRotateDegrees[1]))
				{
					_simpleMotion.returnValue = tmpRotateDegrees[1];
				}
				else {
					Debug.LogError(Motion.MotionPlatform.MotionPlatformData.excelName + "的表格行EXCEL@" + data_row[1] + "中的变量" + tmpRotateDegrees[1] + "在公式表中不存在");
				}
			}

			Debug.Log("SimpleMove Vec:" + tmpVec);
			Vector3 motionVec = Motion_Compute.Vector3Conversion(tmpVec, ref isRight);
			if (!isRight || motionVec.magnitude == 0)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "SPEEDVECTOR", row_id) + "，移动向量格式填写错误！");
				}
				return false;
			}
			//修改参数
			if (_simpleMotion.returnValue != "")
			{
				_simpleMotion.targetValue = (float)VariableManager.GetValue(_simpleMotion.returnValue) + motionVec.magnitude;
			}

			//终止信息记录
			GameObject empty = new GameObject();
			empty.name = "move_empty-" + row_id;
			empty.transform.position = _simpleMotion.StartPos;
			empty.transform.eulerAngles = _simpleMotion.StartEurler;
			//empty.transform.Translate(motionVec, Space.Self);

			empty.transform.parent = _simpleMotion.ParentTrans.parent;
			empty.transform.localPosition += motionVec;

			_simpleMotion.EndPos = empty.transform.position;
			_simpleMotion.EndEurler = empty.transform.eulerAngles;
			GameObject.DestroyImmediate(empty);
			//速度提取
			_simpleMotion.MoveSpeed = Motion_Compute.FloatConversion(data_row[5].ToString(), ref isRight);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "MOVESPEED", row_id) + "，移动速度格式填写错误！");
				}
				return false;
			}
			if (_simpleMotion.CurrentMotion == MotionType.AccelerateMove)
			{  //加速直线运动
				float finalSpeed = Motion_Compute.FloatConversion(data_row[4].ToString(), ref isRight);
				if (!isRight)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "ACCELERATEMOVE", row_id) + "，移动加速度格式填写错误！");
					}
					return false;
				}
				motionVec = _simpleMotion.EndPos - _simpleMotion.StartPos;
				_simpleMotion.AccelerateVec = motionVec.normalized;
				_simpleMotion.StandardTime = motionVec.magnitude / (_simpleMotion.MoveSpeed +
					0.5f * (finalSpeed - _simpleMotion.MoveSpeed));
				_simpleMotion.AccelerateVec = (finalSpeed * _simpleMotion.AccelerateVec -
					_simpleMotion.MoveSpeed * _simpleMotion.AccelerateVec) / _simpleMotion.StandardTime;
				_simpleMotion.SpeedVector = motionVec.normalized * _simpleMotion.MoveSpeed;
			}
			else
			{  //匀速直线运动
				//运动信息获取
				_simpleMotion.StandardTime = motionVec.magnitude / _simpleMotion.MoveSpeed;
				_simpleMotion.SpeedVector = motionVec / _simpleMotion.StandardTime;
			}
			_simpleMotion.EndTime = _simpleMotion.StandardTime / _simpleMotion.SpeedRate;
			motion_list.Add(_simpleMotion);

			//参数表记录
			if (Motion_Data.isEditor && MotionPlatformData.currentMotion == MotionPlatformState.Teaching && _simpleMotion.returnValue != "")
			{
				Hashtable cameraHashTable = new Hashtable();

				for (int i = 0; i < VariableManager._varList.Count; i++)
				{
					//Debug.Log(i + "," + _simpleMotion.returnValue + "," + test[i]);
					if (_simpleMotion.returnValue == VariableManager._varList[i])
					{
						cameraHashTable.Add(VariableManager._varList[i], _simpleMotion.targetValue);
					}
					else
					{
						cameraHashTable.Add(VariableManager._varList[i], VariableManager.GetValue(VariableManager._varList[i]));
					}
				}
				//MotionPara.stateControlManager.AddState(MotionPara.excelName, MotionPara.mainRowNumber + 2, "State_Variables", "Variables", cameraHashTable);

				Type _t = Motion_TypeGet.MotionTypeGet("ReflectionManager");
				if (!MotionPlatformData.st_ReflectionManager && _t != null)
				{
					MotionPlatformData.st_ReflectionManager = (MonoBehaviour)GameObject.FindObjectOfType(_t);
				}

				if (MotionPlatformData.st_ReflectionManager && _t != null)
				{
					MethodInfo methodInfo = _t.GetMethod("ReflectionAddState");
					BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;
					object[] para = new object[] { MotionPlatformData.excelName, MotionPlatformData.mainRowNumber + 2, "State_Variables", "Variables", cameraHashTable };
					methodInfo.Invoke(MotionPlatformData.st_ReflectionManager, flag, Type.DefaultBinder, para, null);
				}
			}

			//自动装配处理
			if (Motion_Data.IsAutoAssemble)
			{
				//用于记录自动装配信息
				string[] autoAssembleContents = new string[data_row.Table.Columns.Count];
				for (int i = 0; i < data_row.Table.Columns.Count; i++)
				{
					autoAssembleContents[i] = data_row[i].ToString();
				}

				if (_simpleMotion.CurrentMotion == MotionType.AccelerateMove) //有匀加速运动
				{
					string tmp_AcceleratedMove = autoAssembleContents[4];
					autoAssembleContents[4] = autoAssembleContents[5];
					autoAssembleContents[5] = tmp_AcceleratedMove;
				}

				Vector3 autoVec = -Motion_Compute.Vector3Conversion(data_row[6].ToString(), ref isRight);

				autoAssembleContents[6] = autoVec.x + "," + autoVec.y + "," + autoVec.z;

				//更新当前行
				Motion_AutoAssemblyAndTime.AutoUpdate(autoAssembleContents, "EXCEL", 1);
			}

			return true;
		}

	}

	/// <summary>
	/// 简单旋转；
	/// </summary>
	public class Motion_Excel_SimpleRotate : IMotionFunctionInfo
	{

		public bool InfoGet(DataRow data_row, string row_id, DataTable group_table, IList<IMotion> motion_list, IList<IList<IMotion>> complex_motion_list)
		{
			BasicMotion _simpleMotion = new BasicMotion();


			bool isRight = true;
			//运动类型
			_simpleMotion.CurrentMotion = MotionType.RotateOnly;
			//Group Column
			int groupColumn = Motion_Compute.IntConversion(data_row[2].ToString(), ref isRight) + 1;
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group填写错误！");
				}
				return false;
			}
			if (groupColumn >= group_table.Columns.Count || groupColumn <= 0)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group组号超出范围");
				}
				return false;
			}
			//运动物体信息
			string objName = "";
			objName = (string)group_table.Rows[0][groupColumn].ToString();
			try
			{
				_simpleMotion.ParentTrans = GameObject.Find(objName).transform;
			}
			catch
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，简单旋转Group第一个物体填写错误，" + objName + "该物体在场景中不存在！");
				}
				return false;
			}
			_simpleMotion.RotateCenter = _simpleMotion.ParentTrans.position;
			for (int i = 1; i < group_table.Rows.Count; i++)
			{
				objName = (string)group_table.Rows[i][groupColumn].ToString();
				if (objName == "")
					break;
				Transform tempTrans = null;
				try
				{
					tempTrans = GameObject.Find(objName).transform;
				}
				catch
				{
					isRight = false;
					Debug.LogError(objName + "，该物体在场景中不存在！");
					continue;
				}
				_simpleMotion.ChildList.Add(tempTrans);
				_simpleMotion.ParentList.Add(tempTrans.parent);
				_simpleMotion.RotateCenter = (_simpleMotion.RotateCenter + tempTrans.position) / 2;
			}
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，Group号对应的Group表填写有错误！");
				}
				return false;
			}
			//起始信息记录
			_simpleMotion.StartPos = _simpleMotion.ParentTrans.position;
			_simpleMotion.StartEurler = _simpleMotion.ParentTrans.eulerAngles;
			if ((string)data_row[8].ToString() != "")
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "ACCELERATEROTATE", row_id) + "，暂不支持匀加速旋转！");
				}
			}
			//旋转轴
			_simpleMotion.RotateAxis = Motion_Compute.Vector3Conversion(data_row[7].ToString(), ref isRight);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "ROTATEAXIS", row_id) + "，旋转轴格式填写错误！");
				}
				return false;
			}
			//旋转速度
			_simpleMotion.RotateSpeed = Motion_Compute.FloatConversion(data_row[9].ToString(), ref isRight);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "ANGLEVECTOR", row_id) + "，旋转速度格式填写错误！");
				}
				return false;
			}
			//旋转角度
			string tmpRotateDegree = data_row[10].ToString();
			//Debug.Log("tmpRotateDegree :" + tmpRotateDegree);
			//修改参数
			if (tmpRotateDegree.Contains("$") && tmpRotateDegree[0] != '$')
			{
				string[] tmpRotateDegrees = tmpRotateDegree.Split('$');
				tmpRotateDegree = tmpRotateDegrees[0];

				_simpleMotion.returnValue = tmpRotateDegrees[1];
			}

			float rotateDegree = Motion_Compute.FloatConversion(tmpRotateDegree, ref isRight);
			//修改参数
			if (_simpleMotion.returnValue != "")
			{
				_simpleMotion.targetValue = (float)VariableManager.GetValue(_simpleMotion.returnValue) + rotateDegree;
				//Debug.Log("targetValue:" + _simpleMotion.targetValue);
			}

			if (rotateDegree <= 0)
			{
				isRight = false;
				Debug.LogError("旋转角度不能为负数！");
			}
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "DEGREE", row_id) + "，旋转角度格式填写错误！");
				}
				return false;
			}
			//旋转模式
			string rotateType = (string)data_row[11].ToString();
			if (rotateType == "")
			{
				//普通旋转
				_simpleMotion.RotateAxis = _simpleMotion.ParentTrans.TransformDirection(_simpleMotion.RotateAxis);
			}
			else if (rotateType.ToUpper() == "WORLD")
			{
				//绕世界坐标轴旋转
				//Do Nothing
			}
			else
			{
				//绕某一物体旋转
				Transform tempTrans;
				try
				{
					tempTrans = GameObject.Find(rotateType).transform;
				}
				catch
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "REFER", row_id) + "，参照物体填写错误！");
					}
					return false;
				}
				_simpleMotion.RotateAxis = tempTrans.TransformDirection(_simpleMotion.RotateAxis);
				_simpleMotion.RotateCenter = tempTrans.position;
			}
			_simpleMotion.StandardTime = rotateDegree / _simpleMotion.RotateSpeed;
			//终止信息记录
			GameObject empty = new GameObject();
			empty.name = "rotate_empty-" + row_id;
			empty.transform.position = _simpleMotion.StartPos;
			empty.transform.eulerAngles = _simpleMotion.StartEurler;
			empty.transform.RotateAround(_simpleMotion.RotateCenter, _simpleMotion.RotateAxis, rotateDegree);
			_simpleMotion.EndPos = empty.transform.position;
			_simpleMotion.EndEurler = empty.transform.eulerAngles;
			GameObject.DestroyImmediate(empty);
			_simpleMotion.EndTime = _simpleMotion.StandardTime / _simpleMotion.SpeedRate;

			motion_list.Add(_simpleMotion);

			//参数表记录
			if (Motion_Data.isEditor && MotionPlatformData.currentMotion == MotionPlatformState.Teaching && _simpleMotion.returnValue != "")
			{
				Hashtable cameraHashTable = new Hashtable();

				for (int i = 0; i < VariableManager._varList.Count; i++)
				{
					//Debug.Log(i + "," + _simpleMotion.returnValue + "," + test[i]);
					if (_simpleMotion.returnValue == VariableManager._varList[i])
					{
						cameraHashTable.Add(VariableManager._varList[i], _simpleMotion.targetValue);
					}
					else
					{
						cameraHashTable.Add(VariableManager._varList[i], VariableManager.GetValue(VariableManager._varList[i]));
					}
				}
				//MotionPara.stateControlManager.AddState(MotionPara.excelName, MotionPara.mainRowNumber + 2, "State_Variables", "Variables", cameraHashTable);

				Type _t = Motion_TypeGet.MotionTypeGet("ReflectionManager");
				if (!MotionPlatformData.st_ReflectionManager && _t != null)
				{
					MotionPlatformData.st_ReflectionManager = (MonoBehaviour)GameObject.FindObjectOfType(_t);
				}
				
				if (MotionPlatformData.st_ReflectionManager && _t != null)
				{
					MethodInfo methodInfo = _t.GetMethod("ReflectionAddState");
					BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;
					object[] para = new object[] { MotionPlatformData.excelName, MotionPlatformData.mainRowNumber + 2, "State_Variables", "Variables", cameraHashTable };
					methodInfo.Invoke(MotionPlatformData.st_ReflectionManager, flag, Type.DefaultBinder, para, null);
				}
			}

			//自动装配处理
			if (Motion_Data.IsAutoAssemble)
			{
				//用于记录自动装配信息
				string[] autoAssembleContents = new string[data_row.Table.Columns.Count];
				for (int i = 0; i < data_row.Table.Columns.Count; i++)
				{
					autoAssembleContents[i] = data_row[i].ToString();
				}

				if (_simpleMotion.CurrentMotion == MotionType.AccelerateMove) //有匀加速运动
				{
					string tmp_AcceleratedMove = autoAssembleContents[8];
					autoAssembleContents[8] = autoAssembleContents[9];
					autoAssembleContents[9] = tmp_AcceleratedMove;
				}

				Vector3 autoVec = -Motion_Compute.Vector3Conversion(data_row[7].ToString(), ref isRight);

				autoAssembleContents[7] = autoVec.x + "," + autoVec.y + "," + autoVec.z;

				//更新当前行
				Motion_AutoAssemblyAndTime.AutoUpdate(autoAssembleContents, "EXCEL", 1);
			}

			return true;
		}

	}

	/// <summary>
	/// 平移+旋转；
	/// </summary>
	public class Motion_Excel_MoveAndRotate : IMotionFunctionInfo
	{

		public bool InfoGet(DataRow data_row, string row_id, DataTable group_table, IList<IMotion> motion_list, IList<IList<IMotion>> complex_motion_list)
		{
			BasicMotion _simpleMotion = new BasicMotion();
			
			bool isRight = true;
			//运动类型
			if (data_row[11].ToString() == "")
			{  //绕同一中心旋转
				_simpleMotion.CurrentMotion = MotionType.MoveRotateSingle;
			}
			else
			{  //绕各自中心旋转
				_simpleMotion.CurrentMotion = MotionType.MoveRotateEvery;
			}
			//Group Column
			int groupColumn = Motion_Compute.IntConversion(data_row[2].ToString(), ref isRight) + 1;
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group填写错误！");
				}
				return false;
			}
			if (groupColumn >= group_table.Columns.Count || groupColumn <= 0)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group组号超出范围");
				}
				return false;
			}
			//运动物体信息
			string objName = "";
			GameObject emptyObj = new GameObject();
			objName = (string)group_table.Rows[0][groupColumn].ToString();
			try
			{
				_simpleMotion.ParentTrans = GameObject.Find(objName).transform;
			}
			catch
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，平移加旋转运动Group第一个物体填写错误，" + objName + "该物体在场景中不存在！");
				}
				return false;
			}
			_simpleMotion.ChildList.Add(_simpleMotion.ParentTrans);
			_simpleMotion.ParentList.Add(_simpleMotion.ParentTrans.parent);
			emptyObj.name = "move-rotate_empty-" + row_id;
			emptyObj.transform.position = _simpleMotion.ParentTrans.position;
			emptyObj.transform.eulerAngles = _simpleMotion.ParentTrans.eulerAngles;
			_simpleMotion.EmptyObj = emptyObj;
			for (int i = 1; i < group_table.Rows.Count; i++)
			{
				objName = (string)group_table.Rows[i][groupColumn].ToString();
				if (objName == "")
					break;
				Transform tempTrans = null;
				try
				{
					tempTrans = GameObject.Find(objName).transform;
				}
				catch
				{
					isRight = false;
					Debug.LogError(objName + "，该物体在场景中不存在！");
					continue;
				}
				_simpleMotion.ChildList.Add(tempTrans);
				_simpleMotion.ParentList.Add(tempTrans.parent);
			}
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，Group号对应的Group表填写有错误！");
				}
				return false;
			}
			//起始信息记录
			_simpleMotion.StartPos = _simpleMotion.ParentTrans.position;
			_simpleMotion.StartEurler = _simpleMotion.ParentTrans.eulerAngles;
			//平移和旋转动作判断，当【MoveVector:5】有信息时，平移有动作，否则无；
			//当【RotateDegree:9】有时要考虑两个动作谁快谁慢，以慢的时间为标准，没有旋转就报错
			bool _hasMove = true;
			float moveTime = 0;
			float rotateTime = 0;
			string moveStr = (string)data_row[6].ToString();
			Vector3 motionVec = new Vector3(0f, 0f, 0f);
			if (moveStr == "")
			{
				_hasMove = false;
			}
			else
			{
				_hasMove = true;
				//运动向量提取
				motionVec = Motion_Compute.Vector3Conversion(data_row[6].ToString(), ref isRight);
				if (!isRight || motionVec.magnitude == 0)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "SPEEDVECTOR", row_id) + "，移动向量格式填写错误！");
					}
					return false;
				}
				//速度提取
				_simpleMotion.MoveSpeed = Motion_Compute.FloatConversion(data_row[5].ToString(), ref isRight);
				if (!isRight)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "MOVESPEED", row_id) + "，移动速度格式填写错误！");
					}
					return false;
				}
				moveTime = motionVec.magnitude / _simpleMotion.MoveSpeed;
			}
			//旋转轴
			_simpleMotion.RotateAxis = Motion_Compute.Vector3Conversion(data_row[7].ToString(), ref isRight);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "ROTATEAXIS", row_id) + "，旋转轴格式填写错误！");
				}
				return false;
			}
			//旋转速度
			_simpleMotion.RotateSpeed = Motion_Compute.FloatConversion(data_row[9].ToString(), ref isRight);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "ANGLEVECTOR", row_id) + "，旋转速度格式填写错误！");
				}
				return false;
			}
			string rotateStr = (string)data_row[10].ToString();
			if (rotateStr == "")
			{
				if (!_hasMove)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "SPEEDVECTOR", row_id) + "，移动数据填写不全或者应增加旋转角度！");
					}
					return false;
				}
				//以移动的时间为标准，只修正位置
				_simpleMotion.StandardTime = moveTime;
				_simpleMotion.SpeedVector = motionVec / moveTime;
			}
			else
			{
				//旋转角度
				float rotateDegree = Motion_Compute.FloatConversion(data_row[10].ToString(), ref isRight);
				if (!isRight)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "DEGREE", row_id) + "，旋转速度格式填写错误！");
					}
					return false;
				}
				rotateTime = rotateDegree / _simpleMotion.RotateSpeed;
				if (_hasMove)
				{ //对比时间，哪一个长用哪个，修正位置和角度
					if (moveTime > rotateTime)
					{
						_simpleMotion.StandardTime = moveTime;
						_simpleMotion.SpeedVector = motionVec / moveTime;
						_simpleMotion.RotateSpeed = rotateDegree / moveTime;

					}
					else
					{
						_simpleMotion.StandardTime = rotateTime;
						_simpleMotion.MoveSpeed = motionVec.magnitude / rotateTime;
						_simpleMotion.SpeedVector = motionVec / rotateTime;
					}
				}
				else
				{  //以旋转的时间为标准，修正角度
					_simpleMotion.StandardTime = rotateTime;
				}
			}
			//终止信息记录,只修正位置
			//平移改成记录相对位移已经，转换成绝对位置之差
			if (_hasMove)
			{
				emptyObj.transform.Translate(motionVec, Space.Self);
				_simpleMotion.EndPos = emptyObj.transform.position;
				_simpleMotion.SpeedVector = _simpleMotion.ParentTrans.TransformDirection(motionVec).normalized *
					_simpleMotion.MoveSpeed;
			}
			emptyObj.transform.Rotate(_simpleMotion.RotateSpeed * _simpleMotion.StandardTime * _simpleMotion.RotateAxis,
				Space.Self);
			_simpleMotion.EndEurler = emptyObj.transform.eulerAngles;
			emptyObj.transform.position = _simpleMotion.StartPos;
			emptyObj.transform.eulerAngles = _simpleMotion.StartEurler;
			_simpleMotion.EndTime = _simpleMotion.StandardTime / _simpleMotion.SpeedRate;

			motion_list.Add(_simpleMotion);

			//自动装配处理
			if (Motion_Data.IsAutoAssemble)
			{
				//用于记录自动装配信息
				string[] autoAssembleContents = new string[data_row.Table.Columns.Count];
				for (int i = 0; i < data_row.Table.Columns.Count; i++)
				{
					autoAssembleContents[i] = data_row[i].ToString();
				}

				if (data_row[6].ToString() != "")
				{
					Vector3 autoVec1 = -Motion_Compute.Vector3Conversion(data_row[6].ToString(), ref isRight);
					autoAssembleContents[6] = autoVec1.x + "," + autoVec1.y + "," + autoVec1.z;
				}
				if (data_row[7].ToString() != "")
				{
					Vector3 autoVec2 = -Motion_Compute.Vector3Conversion(data_row[7].ToString(), ref isRight);
					autoAssembleContents[7] = autoVec2.x + "," + autoVec2.y + "," + autoVec2.z;
				}
				
				//更新当前行
				Motion_AutoAssemblyAndTime.AutoUpdate(autoAssembleContents, "EXCEL", 1);
			}

			return true;
		}

	}

	/// <summary>
	/// 任意移动；
	/// </summary>
	public class Motion_Excel_RandomMove : IMotionFunctionInfo
	{

		public bool InfoGet(DataRow data_row, string row_id, DataTable group_table, IList<IMotion> motion_list, IList<IList<IMotion>> complex_motion_list)
		{
			BasicMotion _simpleMotion = new BasicMotion();

			bool isRight = true;
			//运动类型
			_simpleMotion.CurrentMotion = MotionType.RandomMotion;
			//Group Column
			int groupColumn = Motion_Compute.IntConversion(data_row[2].ToString(), ref isRight) + 1;
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group填写错误！");
				}
				return false;
			}
			if (groupColumn >= group_table.Columns.Count || groupColumn <= 0)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group组号超出范围");
				}
				return false;
			}
			//运动物体信息
			string objName = "";
			objName = (string)group_table.Rows[0][groupColumn].ToString();
			try
			{
				_simpleMotion.ParentTrans = GameObject.Find(objName).transform;
			}
			catch
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，任意移动Group第一个物体填写错误，" + objName + "该物体在场景中不存在！");
				}
				return false;
			}
			for (int i = 1; i < group_table.Rows.Count; i++)
			{
				objName = (string)group_table.Rows[i][groupColumn].ToString();
				if (objName == "")
					break;
				Transform tempTrans = null;
				try
				{
					tempTrans = GameObject.Find(objName).transform;
				}
				catch
				{
					isRight = false;
					Debug.LogError(objName + "，该物体在场景中不存在！");
					continue;
				}
				_simpleMotion.ChildList.Add(tempTrans);
				_simpleMotion.ParentList.Add(tempTrans.parent);
			}
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，Group号对应的Group表填写有错误！");
				}
				return false;
			}
			//起始信息记录
			_simpleMotion.StartPos = _simpleMotion.ParentTrans.position;
			_simpleMotion.StartEurler = _simpleMotion.ParentTrans.eulerAngles;
			//移动速度确定，如果有自定义移动速度
			float customMoveSpeed = MotionPlatformData.toolMoveSpeed;
			string speedStr = (string)data_row[5].ToString();
			if (speedStr != "")
			{
				customMoveSpeed = Motion_Compute.FloatConversion(speedStr, ref isRight);
				if (!isRight)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "MOVESPEED", row_id) + "，移动速度格式填写错误！");
					}
					return false;
				}
			}
			//旋转速度确定，如果有自定义旋转速度
			float customRotateSpeed = MotionPlatformData.toolRotateSpeed;
			string rotateSpeedStr = (string)data_row[9].ToString();
			if (rotateSpeedStr != "")
			{
				customRotateSpeed = Motion_Compute.FloatConversion(rotateSpeedStr, ref isRight);
				if (!isRight)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "ANGLEVECTOR", row_id) + "，旋转速度格式填写错误！");
					}
					return false;
				}
			}
			//终止位置获取
			GameObject empty = new GameObject();
			empty.name = "random_move_empty-" + row_id;
			Transform finalTrans;
			try
			{
				finalTrans = GameObject.Find((string)data_row[11].ToString()).transform;
			}
			catch
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "REFER", row_id) + "，参考物体填写错误！");
				}
				return false;
			}
			_simpleMotion.EndPos = Motion_Compute.Vector3Conversion((string)data_row[12].ToString(), ref isRight);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "POSITION", row_id) + "，参考位置填写错误！");
				}
				return false;
			}
			_simpleMotion.EndEurler = Motion_Compute.Vector3Conversion((string)data_row[13].ToString(), ref isRight);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "EURLER", row_id) + "，参考角度填写错误！");
				}
				return false;
			}
			empty.transform.parent = finalTrans;
			empty.transform.localPosition = _simpleMotion.EndPos;
			empty.transform.localEulerAngles = _simpleMotion.EndEurler;
			_simpleMotion.EndPos = empty.transform.position;
			_simpleMotion.EndEurler = empty.transform.eulerAngles;
			GameObject.DestroyImmediate(empty);
			//时间计算
			Vector3 motionVec = _simpleMotion.EndPos - _simpleMotion.StartPos;
			Vector3 angleVec = Motion_Compute.GetAngleDiff(_simpleMotion.StartEurler, ref _simpleMotion.EndEurler);
			float moveTime = 0;
			float rotateTime = 0;
			if (motionVec.magnitude != 0)
			{
				moveTime = motionVec.magnitude / customMoveSpeed;
			}
			if (angleVec.magnitude != 0)
			{
				rotateTime = Vector3.Angle(_simpleMotion.StartEurler, _simpleMotion.EndEurler) / customRotateSpeed;
			}
			if (moveTime == 0 && rotateTime == 0)
			{
				Debug.LogError(ErrorLocation.Locate("EXCEL", "REFER", row_id) + "，参考物体所计算出的位移和角度都为0，没有移动！");
				return false;
			}
			if (moveTime > rotateTime)
			{
				_simpleMotion.StandardTime = moveTime;
				_simpleMotion.SpeedVector = motionVec / moveTime;
				_simpleMotion.RotateSpeed = Vector3.Angle(_simpleMotion.StartEurler, _simpleMotion.EndEurler) / moveTime;
				_simpleMotion.AngleVector = angleVec / moveTime;
			}
			else
			{
				_simpleMotion.StandardTime = rotateTime;
				_simpleMotion.SpeedVector = motionVec / rotateTime;
				_simpleMotion.MoveSpeed = motionVec.magnitude / rotateTime;
				_simpleMotion.AngleVector = angleVec / rotateTime;
			}
			_simpleMotion.EndTime = _simpleMotion.StandardTime / _simpleMotion.SpeedRate;

			motion_list.Add(_simpleMotion);

			//自动装配处理
			if (Motion_Data.IsAutoAssemble)
			{
				//用于记录自动装配信息
				string[] autoAssembleContents = new string[data_row.Table.Columns.Count];
				for (int i = 0; i < data_row.Table.Columns.Count; i++)
				{
					autoAssembleContents[i] = data_row[i].ToString();
				}

				GameObject emptyAuto = new GameObject("random_move_empty-" + row_id);
				emptyAuto.transform.position = _simpleMotion.ParentTrans.position;
				emptyAuto.transform.eulerAngles = _simpleMotion.ParentTrans.eulerAngles;
				emptyAuto.transform.parent = finalTrans;
				autoAssembleContents[12] = emptyAuto.transform.localPosition.x + "," + emptyAuto.transform.localPosition.y + "," + emptyAuto.transform.localPosition.z;
				autoAssembleContents[13] = emptyAuto.transform.localEulerAngles.x + "," + emptyAuto.transform.localEulerAngles.y + "," + emptyAuto.transform.localEulerAngles.z;
				emptyAuto.transform.parent = null;
				GameObject.Destroy(emptyAuto);

				//更新当前行
				Motion_AutoAssemblyAndTime.AutoUpdate(autoAssembleContents, "EXCEL", 1);
			}

			return true;
		}

	}


	/// <summary>
	/// 瞬间移动；
	/// </summary>
	public class Motion_Excel_SetPos : IMotionFunctionInfo
	{

		public bool InfoGet(DataRow data_row, string row_id, DataTable group_table, IList<IMotion> motion_list, IList<IList<IMotion>> complex_motion_list)
		{
			BasicMotion _simpleMotion = new BasicMotion();

			bool isRight = true;
			//运动类型
			_simpleMotion.CurrentMotion = MotionType.SetPos;
			//Group Column
			int groupColumn = Motion_Compute.IntConversion(data_row[2].ToString(), ref isRight) + 1;
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group填写错误！");
				}
				return false;
			}
			if (groupColumn >= group_table.Columns.Count || groupColumn <= 0)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group组号超出范围");
				}
				return false;
			}
			//运动物体信息
			string objName = "";
			objName = (string)group_table.Rows[0][groupColumn].ToString();
			try
			{
				_simpleMotion.ParentTrans = GameObject.Find(objName).transform;
			}
			catch
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，瞬移Group第一个物体填写错误，" + objName + "该物体在场景中不存在！");
				}
				return false;
			}
			for (int i = 1; i < group_table.Rows.Count; i++)
			{
				objName = (string)group_table.Rows[i][groupColumn].ToString();
				if (objName == "")
					break;
				Transform tempTrans = null;
				try
				{
					tempTrans = GameObject.Find(objName).transform;
				}
				catch
				{
					isRight = false;
					Debug.LogError(objName + "，该物体在场景中不存在！");
					continue;
				}
				_simpleMotion.ChildList.Add(tempTrans);
				_simpleMotion.ParentList.Add(tempTrans.parent);
			}
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，Group号对应的Group表填写有错误！");
				}
				return false;
			}
			//起始信息记录
			_simpleMotion.StartPos = _simpleMotion.ParentTrans.position;
			_simpleMotion.StartEurler = _simpleMotion.ParentTrans.eulerAngles;
			//终止位置获取
			_simpleMotion.EndPos = Motion_Compute.Vector3Conversion((string)data_row[12].ToString(), ref isRight);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "POSITION", row_id) + "，参考位置填写错误！");
				}
				return false;
			}
			_simpleMotion.EndEurler = Motion_Compute.Vector3Conversion((string)data_row[13].ToString(), ref isRight);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "EURLER", row_id) + "，参考角度填写错误！");
				}
				return false;
			}
			//参考物体
			string refStr = ((string)data_row[11].ToString()).ToUpper();
			Transform finalTrans = null;
			if (refStr != "" && refStr != "WORLD")
			{
				GameObject empty = new GameObject();
				empty.name = "random_move_empty-" + row_id;
				try
				{
					finalTrans = GameObject.Find((string)data_row[11].ToString()).transform;
				}
				catch
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "REFER", row_id) + "，参考物体填写错误！");
					}
					return false;
				}
				empty.transform.parent = finalTrans;
				empty.transform.localPosition = _simpleMotion.EndPos;
				empty.transform.localEulerAngles = _simpleMotion.EndEurler;
				_simpleMotion.EndPos = empty.transform.position;
				_simpleMotion.EndEurler = empty.transform.eulerAngles;
				GameObject.DestroyImmediate(empty);
			}
			_simpleMotion.StandardTime = 0.05f;
			_simpleMotion.EndTime = 0.05f;

			motion_list.Add(_simpleMotion);

			//自动装配处理
			if (Motion_Data.IsAutoAssemble)
			{
				//用于记录自动装配信息
				string[] autoAssembleContents = new string[data_row.Table.Columns.Count];
				for (int i = 0; i < data_row.Table.Columns.Count; i++)
				{
					autoAssembleContents[i] = data_row[i].ToString();
				}

				if (data_row[11].ToString().ToUpper() != "" && data_row[11].ToString().ToUpper() != "WORLD")
				{
					GameObject emptyAuto = new GameObject("set_pos_empty-" + row_id);
					emptyAuto.transform.position = _simpleMotion.ParentTrans.position;
					emptyAuto.transform.eulerAngles = _simpleMotion.ParentTrans.eulerAngles;
					emptyAuto.transform.parent = finalTrans;
					autoAssembleContents[12] = emptyAuto.transform.localPosition.x + "," + emptyAuto.transform.localPosition.y + "," + emptyAuto.transform.localPosition.z;
					autoAssembleContents[13] = emptyAuto.transform.localEulerAngles.x + "," + emptyAuto.transform.localEulerAngles.y + "," + emptyAuto.transform.localEulerAngles.z;
					emptyAuto.transform.parent = null;
					GameObject.Destroy(emptyAuto);
				}
				else
				{
					autoAssembleContents[12] = _simpleMotion.StartPos.x + "," + _simpleMotion.StartPos.y + "," + _simpleMotion.StartPos.z;
					autoAssembleContents[13] = _simpleMotion.StartEurler.x + "," + _simpleMotion.StartEurler.y + "," + _simpleMotion.StartEurler.z;
				}

				//更新当前行
				Motion_AutoAssemblyAndTime.AutoUpdate(autoAssembleContents, "EXCEL", 1);
			}

			return true;
		}

	}

	/// <summary>
	/// 可视化路径运动；
	/// </summary>
	public class Motion_Excel_VisualPath : IMotionFunctionInfo
	{

		public bool InfoGet(DataRow data_row, string row_id, DataTable group_table, IList<IMotion> motion_list, IList<IList<IMotion>> complex_motion_list)
		{
			BasicMotion _simpleMotion = new BasicMotion();

			bool isRight = true;
			//运动类型
			_simpleMotion.CurrentMotion = MotionType.VisualPath;
			//Group Column
			int groupColumn = Motion_Compute.IntConversion((string)data_row[2].ToString(), ref isRight) + 1;
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group填写错误！");
				}
				return false;
			}
			if (groupColumn >= group_table.Columns.Count || groupColumn <= 0)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，运动Group组号超出范围");
				}
				return false;
			}
			//运动物体信息
			string objName = "";
			objName = (string)group_table.Rows[0][groupColumn].ToString();
			try
			{
				_simpleMotion.ParentTrans = GameObject.Find(objName).transform;
			}
			catch
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，可视化路径Group第一个物体填写错误，" + objName + "该物体在场景中不存在！");
				}
				return false;
			}
			for (int i = 1; i < group_table.Rows.Count; i++)
			{
				objName = (string)group_table.Rows[i][groupColumn].ToString();
				if (objName == "")
					break;
				Transform tempTrans = null;
				try
				{
					tempTrans = GameObject.Find(objName).transform;
				}
				catch
				{
					isRight = false;
					Debug.LogError(objName + "，该物体在场景中不存在！");
					continue;
				}
				_simpleMotion.ChildList.Add(tempTrans);
				_simpleMotion.ParentList.Add(tempTrans.parent);
			}
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "GROUP", row_id) + "，Group号对应的Group表填写有错误！");
				}
				return false;
			}
			//移动速度确定，如果有自定义移动速度
			float customMoveSpeed = MotionPlatformData.toolMoveSpeed;
			string speedStr = (string)data_row[5].ToString();
			if (speedStr != "")
			{
				customMoveSpeed = Motion_Compute.FloatConversion(speedStr, ref isRight);
				if (!isRight)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "MOVESPEED", row_id) + "，移动速度格式填写错误！");
					}
					return false;
				}
			}
			//路径信息加载
			string pathName = (string)data_row[4].ToString();
			string isBackString = (string)data_row[7].ToString().ToUpper();
			bool isBack = false;
			if (isBackString == "BACK")
			{
				isBack = true;
			}
			JsonLoad(pathName, _simpleMotion.crSpline, ref isRight, _simpleMotion.ParentTrans, isBack);
			if (!isRight)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("EXCEL", "PATHNAME", row_id) + "，可视化路径名称填写错误！");
				}
				return false;
			}
			//起始信息记录
			_simpleMotion.StartPos = _simpleMotion.crSpline.controlPoints[0];
			_simpleMotion.StartEurler = _simpleMotion.crSpline.rotationList[0];
			//终止位置获取
			string endPosStr = (string)data_row[12].ToString();
			if (endPosStr == "")
			{
				_simpleMotion.EndPos = _simpleMotion.crSpline.controlPoints[_simpleMotion.crSpline.controlPoints.Count - 1];
			}
			else
			{
				_simpleMotion.EndPos = Motion_Compute.Vector3Conversion(endPosStr, ref isRight);
				if (!isRight)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "POSITION", row_id) + "，参考位置填写错误！");
					}
					return false;
				}
			}
			//终止角度获取
			string endEulerStr = (string)data_row[13].ToString();
			if (endEulerStr == "")
			{
				_simpleMotion.EndEurler = _simpleMotion.crSpline.rotationList[_simpleMotion.crSpline.rotationList.Count - 1];
			}
			else
			{
				_simpleMotion.EndEurler = Motion_Compute.Vector3Conversion(endEulerStr, ref isRight);
				if (!isRight)
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "EURLER", row_id) + "，参考角度填写错误！");
					}
					return false;
				}
			}
			
			//参考物体
			string refStr = ((string)data_row[11].ToString()).ToUpper();
			Transform finalTrans = null;
			if (refStr != "" && refStr != "WORLD" && (endEulerStr != "" || endPosStr != ""))
			{
				GameObject empty = new GameObject();
				empty.name = "random_move_empty-" + row_id;
				
				try
				{
					finalTrans = GameObject.Find((string)data_row[11].ToString()).transform;
				}
				catch
				{
					if (Motion_Data.isEditor)
					{
						Debug.LogError(ErrorLocation.Locate("EXCEL", "REFER", row_id) + "，参考物体填写错误！");
					}
					return false;
				}
				empty.transform.parent = finalTrans;
				empty.transform.localPosition = _simpleMotion.EndPos;
				empty.transform.localEulerAngles = _simpleMotion.EndEurler;
				if (endPosStr != "")
				{
					_simpleMotion.EndPos = empty.transform.position;
					_simpleMotion.crSpline.controlPoints[_simpleMotion.crSpline.controlPoints.Count - 1] = empty.transform.position;
				}
				if (endEulerStr != "")
				{
					_simpleMotion.EndEurler = empty.transform.eulerAngles;
					_simpleMotion.crSpline.rotationList[_simpleMotion.crSpline.rotationList.Count - 1] = empty.transform.eulerAngles;
				}
				GameObject.DestroyImmediate(empty);
			}
			AngleOptimization(_simpleMotion.crSpline.rotationList);
			_simpleMotion.crSpline.pts = _simpleMotion.crSpline.PathControlPointGenerator(_simpleMotion.crSpline.controlPoints.ToArray());
			_simpleMotion.StandardTime = _simpleMotion.crSpline.TimeGet(_simpleMotion.crSpline.pts, customMoveSpeed);
			_simpleMotion.crSpline.TimeRateGenerator(_simpleMotion.crSpline.rotationList.Count);
			_simpleMotion.EndTime = _simpleMotion.StandardTime / _simpleMotion.SpeedRate;

			motion_list.Add(_simpleMotion);

			//自动装配处理
			if (Motion_Data.IsAutoAssemble)
			{
				//用于记录自动装配信息
				string[] autoAssembleContents = new string[data_row.Table.Columns.Count];
				for (int i = 0; i < data_row.Table.Columns.Count; i++)
				{
					autoAssembleContents[i] = data_row[i].ToString();
				}

				if (autoAssembleContents[7].ToUpper() == "BACK")
				{
					autoAssembleContents[7] = "";
				}
				else
				{
					autoAssembleContents[7] = "BACK";
				}

				if (refStr != "" && refStr != "WORLD")
				{
					GameObject emptyAuto = new GameObject("visual_path_empty-" + row_id);
					emptyAuto.transform.position = _simpleMotion.ParentTrans.position;
					emptyAuto.transform.eulerAngles = _simpleMotion.ParentTrans.eulerAngles;
					emptyAuto.transform.parent = finalTrans;
					autoAssembleContents[12] = emptyAuto.transform.localPosition.x + "," + emptyAuto.transform.localPosition.y + "," + emptyAuto.transform.localPosition.z;
					autoAssembleContents[13] = emptyAuto.transform.localEulerAngles.x + "," + emptyAuto.transform.localEulerAngles.y + "," + emptyAuto.transform.localEulerAngles.z;
					emptyAuto.transform.parent = null;
					GameObject.Destroy(emptyAuto);
				}
				else
				{
					autoAssembleContents[12] = _simpleMotion.StartPos.x + "," + _simpleMotion.StartPos.y + "," + _simpleMotion.StartPos.z;
					autoAssembleContents[13] = _simpleMotion.StartEurler.x + "," + _simpleMotion.StartEurler.y + "," + _simpleMotion.StartEurler.z;
				}

				//更新当前行
				Motion_AutoAssemblyAndTime.AutoUpdate(autoAssembleContents, "EXCEL", 1);
			}

			return true;
		}

		//Json文件加载
		private void JsonLoad(string path_name, CRSpline crSpline, ref bool is_right, Transform parent_trans, bool is_back)
		{
			string filePath = MotionPlatformData.taskRootPath + MotionPlatformData.taskName + "/PathControl.json";
			if (File.Exists(filePath))
			{
				JsonOperator jsonOp = new JsonOperator();
				DataTable jsonTable = jsonOp.JsonReader(filePath, path_name);
				if (jsonTable == null)
				{
					Debug.LogError(path_name + ", 该路径名称不存在！");
					return;
				}
				if (is_back)
				{
					GameObject loadEmpty = new GameObject();
					loadEmpty.name = "JsonLoad_empty";
					GameObject loadFather = new GameObject();
					loadEmpty.name = "JsonLoad_Father";
					GameObject loadSon = new GameObject();
					loadSon.name = "JsonLoad_Son";
					loadSon.transform.parent = loadFather.transform;
					Vector3 endEulerAngles = ConvertToVector3((string)jsonTable.Rows[jsonTable.Rows.Count - 1][1].ToString());
					loadSon.transform.localEulerAngles = endEulerAngles;
					loadSon.transform.parent = null;
					loadFather.transform.parent = loadSon.transform;
					loadSon.transform.eulerAngles = parent_trans.eulerAngles;
					loadFather.transform.parent = null;
					loadFather.transform.position = parent_trans.position;
					loadEmpty.transform.parent = loadFather.transform;
					for (int i = 0; i < jsonTable.Rows.Count; i++)
					{
						loadEmpty.transform.localPosition = ConvertToVector3((string)jsonTable.Rows[i][0].ToString());
						loadEmpty.transform.localEulerAngles = ConvertToVector3((string)jsonTable.Rows[i][1].ToString());
						crSpline.controlPoints.Add(loadEmpty.transform.position);
						crSpline.rotationList.Add(loadEmpty.transform.eulerAngles);
						crSpline.cameraViewList.Add(float.Parse((string)jsonTable.Rows[i][2].ToString()));
					}
					Vector3 posDiff = crSpline.controlPoints[crSpline.controlPoints.Count - 1] - crSpline.controlPoints[0];
					for (int i = 0; i < crSpline.controlPoints.Count; i++)
					{
						crSpline.controlPoints[i] = crSpline.controlPoints[i] - posDiff;
					}
					crSpline.controlPoints.Reverse();
					crSpline.rotationList.Reverse();
					crSpline.cameraViewList.Reverse();
					GameObject.DestroyImmediate(loadEmpty);
					GameObject.DestroyImmediate(loadFather);
					GameObject.DestroyImmediate(loadSon);
				}
				else
				{
					GameObject loadEmpty = new GameObject();
					loadEmpty.name = "JsonLoad_empty";
					loadEmpty.transform.parent = parent_trans;
					for (int i = 0; i < jsonTable.Rows.Count; i++)
					{
						loadEmpty.transform.localPosition = ConvertToVector3((string)jsonTable.Rows[i][0].ToString());
						loadEmpty.transform.localEulerAngles = ConvertToVector3((string)jsonTable.Rows[i][1].ToString());
						crSpline.controlPoints.Add(loadEmpty.transform.position);
						crSpline.rotationList.Add(loadEmpty.transform.eulerAngles);
						crSpline.cameraViewList.Add(float.Parse((string)jsonTable.Rows[i][2].ToString()));
					}
					GameObject.DestroyImmediate(loadEmpty);
				}
			}
			else
			{
				Debug.LogError(filePath + ", 该文件不存在！");
			}
		}

		//string to vector3
		private Vector3 ConvertToVector3(string vec_string)
		{
			string[] stringArray = vec_string.Split(',');
			Vector3 rVec = Vector3.zero;
			rVec.x = float.Parse(stringArray[0]);
			rVec.y = float.Parse(stringArray[1]);
			rVec.z = float.Parse(stringArray[2]);
			return rVec;
		}

		//角度值优化，因为角度非常不确定，在类似90和-270之间
		private void AngleOptimization(List<Vector3> rotation_list)
		{
			for (int i = 1; i < rotation_list.Count; i++)
			{
				Vector3 tempVec = rotation_list[i];
				tempVec.x = AngleClerp(rotation_list[i - 1].x, rotation_list[i].x, 1f);
				tempVec.y = AngleClerp(rotation_list[i - 1].y, rotation_list[i].y, 1f);
				tempVec.z = AngleClerp(rotation_list[i - 1].z, rotation_list[i].z, 1f);
				rotation_list[i] = tempVec;
			}
		}

		//角度修改使其符合实际（类似-90和270这种情况处理）
		private float AngleClerp(float start, float end, float value)
		{
			float min = 0.0f;
			float max = 360.0f;
			float half = Mathf.Abs((max - min) / 2.0f);
			float retval = 0.0f;
			float diff = 0.0f;
			if ((end - start) < -half)
			{
				diff = ((max - start) + end) * value;
				retval = start + diff;
			}
			else if ((end - start) > half)
			{
				diff = -((max - end) + start) * value;
				retval = start + diff;
			}
			else retval = start + (end - start) * value;
			return retval;
		}

	}

}
